﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using FwProject.Core.SettlementInfoModel;
using FwProject.PrePaymentInfo.Dto;
using Newtonsoft.Json;
using X.PagedList;
using Abp.Authorization;
namespace FwProject.PrePaymentInfo
{
    /// <summary>
    /// 缴款
    /// </summary>
    [AbpAuthorize]
    public class PaymentInfoAppService : FwProjectAppServiceBase, IPaymentInfoAppService
    {
        public readonly IRepository<PaymentInfoModel, Guid> _repositoryPaymentInfo;
        public readonly IRepository<ReceiptInfoModel, Guid> _repositoryReceiptInfo;
        public readonly IRepository<PaymentInfoByReceipt, Guid> _repositoryPaymentInfoByReceipt;
        public readonly IRepository<SettlementInfo, Guid> _repositorySettlementInfo;
        public readonly IRepository<ReceiptInfoBySettlementModel, Guid> _repositoryReceiptInfoBySettlementModel;
        public IGuidGenerator _guid { get; set; }

        public PaymentInfoAppService(IRepository<PaymentInfoModel, Guid> repositoryPaymentInfo,
            IRepository<ReceiptInfoModel, Guid> repositoryReceiptInfo,
             IRepository<PaymentInfoByReceipt, Guid> repositoryPaymentInfoByReceipt,
             IRepository<SettlementInfo, Guid> repositorySettlementInfo,
             IRepository<ReceiptInfoBySettlementModel, Guid> repositoryReceiptInfoBySettlementModel)
        {
            _repositoryReceiptInfoBySettlementModel = repositoryReceiptInfoBySettlementModel;
            _repositorySettlementInfo = repositorySettlementInfo;
            _repositoryPaymentInfoByReceipt = repositoryPaymentInfoByReceipt;
            _repositoryPaymentInfo = repositoryPaymentInfo;
            _repositoryReceiptInfo = repositoryReceiptInfo;

            _guid = SequentialGuidGenerator.Instance;
        }
        /// <summary>
        /// 后台生成生成缴款凭证
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<Guid> Create(Guid[] ids)
        {
            var user = await base.GetCurrentUserAsync();
            PaymentInfoModel model = new PaymentInfoModel();
            model.Id = _guid.Create();
            List<PaymentInfoByReceipt> list = new List<PaymentInfoByReceipt>();

            foreach (var i in ids)
            {
                var receiptModel = _repositoryReceiptInfo.GetAllIncluding(o => o.RestaurantInfoModel).Where(o => o.Id == i).FirstOrDefault();
                receiptModel.PaymentState = PaymentState.已缴款;
                receiptModel.ReceiptInfoStatus = ReceiptInfoStatus.已审核;
                receiptModel.ToVoid = ToVoidStatus.未作废;
                receiptModel.PaymentTime = DateTime.Now;
                receiptModel.DateofPayment = DateTime.Now;
                receiptModel.PaymentinfoId = model.Id;

                receiptModel.PaymentPersonUserId = user.Id;
                receiptModel.PaymentPerson = user.Name;

                model.PaymentPerson = receiptModel.AgentPeoper;
                model.PaymentPersonId = receiptModel.AgentPeoperUserId;

                PaymentInfoByReceipt rd = new PaymentInfoByReceipt()
                {
                    RestaurnatId = receiptModel.RestaurantId,
                    RestaurantName = receiptModel.RestaurantInfoModel.RestaurantName,
                    TaskBackAmount = receiptModel.TaskBackAmount,
                    ReceiptInfoNumber = receiptModel.ReceiptInfoNumber,
                    ReceiptInfoId = i,
                    PaymentInfoId = model.Id,
                    Id = _guid.Create()
                };
                //生成缴款明细
                _repositoryPaymentInfoByReceipt.Insert(rd);
                //var smodelList = _repositorySettlementInfo.GetAll().Where(o => o.ReceiptInfoId == receiptModel.Id);
                //foreach (var item in smodelList)
                //{
                //    item.RestaurantPayStatus = RestaurantPayStatus.已缴款;

                //}

            }
            model.AgentPeoperId = user.Id;
            model.AgentPeoper = user.Name;
            
            model.FactoryinfoId = user.FactoryinfoId.Value;
            model.RemarksConten = JsonConvert.SerializeObject(list);

            return await _repositoryPaymentInfo.InsertAndGetIdAsync(model);
        }

        public async Task<PaymentInfoDto> GetByReceiptInfoIdAsync(Guid PaymentinfoId)
        {

            var list = _repositoryPaymentInfoByReceipt.GetAll().Where(o => o.PaymentInfoId == PaymentinfoId);//缴款对应收款
            var paymentModel = await _repositoryPaymentInfo.GetAsync(PaymentinfoId);//收款
            PaymentInfoDto dto = new PaymentInfoDto();
            dto.Id = paymentModel.Id;
            dto.PaymentNumber = paymentModel.PaymentNumber;
            dto.CreationTime = paymentModel.CreationTime;
            dto.AgentPeoperUserId = paymentModel.AgentPeoperId;
            dto.AgentPeoper = paymentModel.AgentPeoper;
            dto.PaymentPersonUserId = paymentModel.PaymentPersonId;
            dto.PaymentPerson = paymentModel.PaymentPerson;
            dto.TotalPrice = list.Sum(o => o.TaskBackAmount);
            dto.RemarksConten = paymentModel.RemarksConten;
            dto.ReceiptDetailsDto = list.MapTo<List<ReceiptInfoModelDto>>();

            return dto;
        }

        /// <summary>
        /// 查询缴款凭证
        /// </summary>
        /// <returns></returns>
        public async Task<IPagedList<PaymentInfoDto>> GetPagedListAsync(int pageIdx, int pageSize, DateTime? beginTime, DateTime? endTime, long? AgentPeoperUserId, long? PaymentPerson, string PaymentNumber)
        {
            var model = _repositoryPaymentInfo.GetAll();
            var receipt = _repositoryReceiptInfo.GetAllIncluding(o => o.RestaurantInfoModel);
            var user = await base.GetCurrentUserAsync();
            var data = model.GroupJoin(_repositoryPaymentInfoByReceipt.GetAll(), a => a.Id, b => b.PaymentInfoId, (a, b) => new PaymentInfoDto
            {
                Id = a.Id,
                CreationTime = a.CreationTime,
                PaymentNumber = a.PaymentNumber,
                AgentPeoperUserId = a.AgentPeoperId,
                AgentPeoper = a.AgentPeoper,
                PaymentPersonUserId = a.PaymentPersonId,
                PaymentPerson = a.PaymentPerson,
                TotalPrice = b.Where(o => o.ToVoid == ToVoidStatus.未作废).Sum(o => o.TaskBackAmount),
                ReceiptDetailsDto = b.MapTo<List<ReceiptInfoModelDto>>()
            });
            if (beginTime.HasValue)
                data = data.Where(o => o.CreationTime >= beginTime);
            if (endTime.HasValue)
                data = data.Where(o => o.CreationTime <= endTime.Value.AddHours(24));
            if (AgentPeoperUserId.HasValue)
                data = data.Where(o => o.AgentPeoperUserId == AgentPeoperUserId);
            if (PaymentPerson.HasValue)
                data = data.Where(o => o.PaymentPersonUserId == PaymentPerson);
            if (!string.IsNullOrEmpty(PaymentNumber))
                data = data.Where(o => o.PaymentNumber == PaymentNumber);

            return await data.OrderByDescending(o => o.CreationTime).ToPagedListAsync(pageIdx, pageSize);
        }
        public async Task<List<PaymentInfoDto>> GetAllListAsync(DateTime? beginTime, DateTime? endTime, long? AgentPeoperUserId, long? PaymentPerson, string PaymentNumber)
        {
            var model = _repositoryPaymentInfo.GetAll();
            var receipt = _repositoryReceiptInfo.GetAllIncluding(o => o.RestaurantInfoModel);
            var user = await base.GetCurrentUserAsync();
            var data = model.GroupJoin(_repositoryPaymentInfoByReceipt.GetAll(), a => a.Id, b => b.PaymentInfoId, (a, b) => new PaymentInfoDto
            {
                Id = a.Id,
                CreationTime = a.CreationTime,
                PaymentNumber = a.PaymentNumber,
                AgentPeoperUserId = a.AgentPeoperId,
                AgentPeoper = a.AgentPeoper,
                PaymentPersonUserId = a.PaymentPersonId,
                PaymentPerson = a.PaymentPerson,
                TotalPrice = b.Sum(o => o.TaskBackAmount),
                ReceiptDetailsDto = b.MapTo<List<ReceiptInfoModelDto>>()
            });
            if (beginTime.HasValue)
                data = data.Where(o => o.CreationTime >= beginTime);
            if (endTime.HasValue)
                data = data.Where(o => o.CreationTime <= endTime.Value.AddHours(24));
            if (AgentPeoperUserId.HasValue)
                data = data.Where(o => o.AgentPeoperUserId == AgentPeoperUserId);
            if (PaymentPerson.HasValue)
                data = data.Where(o => o.PaymentPersonUserId == PaymentPerson);
            if (!string.IsNullOrEmpty(PaymentNumber))
                data = data.Where(o => o.PaymentNumber == PaymentNumber);

            return await data.OrderByDescending(o => o.CreationTime).ToListAsync();
        }



        /// <summary>
        /// 收款单作废核作废
        /// </summary>
        /// <param name="ReceiptInfoId"></param>
        public void ToVoid(Guid ReceiptInfoId)
        {
            var model = _repositoryPaymentInfoByReceipt.GetAll().Where(o => o.ReceiptInfoId == ReceiptInfoId && o.ToVoid == ToVoidStatus.未作废).FirstOrDefault();
            if (model != null)
            {
                model.ToVoid = ToVoidStatus.已作废;
                model.ToVoidTime = DateTime.Now;
            }
            var m = _repositoryReceiptInfo.Get(ReceiptInfoId);
            m.ReceiptInfoStatus = ReceiptInfoStatus.退回;
            m.ToVoid = ToVoidStatus.已作废;
            m.PaymentinfoId = null;
            m.PaymentState = PaymentState.未缴款;
            m.PaymentTime = null;
            m.DateofPayment = null;
            ///所有的收据变成未交款
            var listBySettlment = _repositoryReceiptInfoBySettlementModel.GetAll().Where(o => o.ReceiptInfoId == ReceiptInfoId && o.ToVoidStatus == ToVoidStatus.未作废);
            foreach (var item in listBySettlment)
            {
                item.ToVoidStatus = ToVoidStatus.已作废;
                var smodel = _repositorySettlementInfo.GetAll().Where(o => o.Id == item.SettlementId).FirstOrDefault();
                if (smodel != null)
                {
                    smodel.ReceivedDiscount -= item.PreferentialAmount;
                    smodel.UsePrePayment -= item.UsePrePayment;
                    smodel.ReceivedPrice -= item.TaskBackAmount;

                    if(_repositoryReceiptInfoBySettlementModel.GetAll().Where(o=>o.SettlementId==item.SettlementId && o.Id!=item.Id && o.ToVoidStatus == ToVoidStatus.未作废).Count()>0)
                      smodel.RestaurantPayStatus = RestaurantPayStatus.部分收款;
                     else
                        smodel.RestaurantPayStatus = RestaurantPayStatus.未收款;
                    smodel.ReceiptInfoId = null;
                }

            }
        }

        /// <summary>
        /// 收款单反审核
        /// </summary>
        /// <param name="ReceiptInfoId"></param>
        public void Antiaudit(Guid ReceiptInfoId)
        {
            var model = _repositoryPaymentInfoByReceipt.GetAll().Where(o => o.ReceiptInfoId == ReceiptInfoId && o.ToVoid == ToVoidStatus.未作废).FirstOrDefault();
            if (model != null)
            {
                model.ToVoid = ToVoidStatus.已作废;
                model.ToVoidTime = DateTime.Now;
            }
            var m = _repositoryReceiptInfo.Get(ReceiptInfoId);
            m.ReceiptInfoStatus = ReceiptInfoStatus.退回;
            m.PaymentinfoId = null;
            m.PaymentState = PaymentState.未缴款;
            m.PaymentTime = null;
            m.DateofPayment = null;
        }
    }
}
